using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ThridGroup.ERP.Application.Contracts.DTO.WarehouseManagement;
using ThridGroup.ERP.EntityFrameworkCore;
using ThridGroup.ERP.WarehouseManagement;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore;

namespace ThridGroup.ERP.Application.WarehouseManagement
{
    /// <summary>
    /// 库区设置服务实现
    /// </summary>
    public class WarehouseAreaSettingService : IWarehouseAreaSettingService
    {
        private readonly IDbContextProvider<ERPDbContext> _dbContextProvider;

        public WarehouseAreaSettingService(IDbContextProvider<ERPDbContext> dbContextProvider)
        {
            _dbContextProvider = dbContextProvider;
        }

        /// <summary>
        /// 获取所有库区设置
        /// </summary>
        /// <returns>库区设置列表</returns>
        public async Task<List<WarehouseAreaSettingDto>> GetAllAsync()
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var query = from area in dbContext.Set<WarehouseAreaSettingModel>()
                        join warehouse in dbContext.Set<WarehouseSettingModel>()
                            on area.WarehouseId equals warehouse.Id into warehouseJoin
                        from warehouse in warehouseJoin.DefaultIfEmpty()
                        select new WarehouseAreaSettingDto
                        {
                            Id = area.Id,
                            AreaCode = area.AreaCode,
                            AreaName = area.AreaName,
                            WarehouseId = area.WarehouseId,
                            WarehouseName = warehouse != null ? warehouse.DepotName : string.Empty,
                            Area = area.Area,
                            Remark = area.Remark,
                            // 设置默认值
                            Location = string.Empty,
                            ResponsiblePerson = string.Empty,
                            AreaType = string.Empty,
                            StorageType = string.Empty,
                            TemperatureRequirement = string.Empty,
                            HumidityRequirement = string.Empty,
                            MaxCapacity = 0,
                            CurrentUsage = 0,
                            Status = true,
                            CreatedTime = DateTime.Now,
                            UpdatedTime = null
                        };

            return await query.ToListAsync();
        }

        /// <summary>
        /// 获取指定仓库的库区设置列表
        /// </summary>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns>库区设置列表</returns>
        public async Task<List<WarehouseAreaSettingDto>> GetByWarehouseIdAsync(int warehouseId)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var query = from area in dbContext.Set<WarehouseAreaSettingModel>()
                        join warehouse in dbContext.Set<WarehouseSettingModel>()
                            on area.WarehouseId equals warehouse.Id into warehouseJoin
                        from warehouse in warehouseJoin.DefaultIfEmpty()
                        where area.WarehouseId == warehouseId
                        select new WarehouseAreaSettingDto
                        {
                            Id = area.Id,
                            AreaCode = area.AreaCode,
                            AreaName = area.AreaName,
                            WarehouseId = area.WarehouseId,
                            WarehouseName = warehouse != null ? warehouse.DepotName : string.Empty,
                            Area = area.Area,
                            Remark = area.Remark,
                            // 设置默认值
                            Location = string.Empty,
                            ResponsiblePerson = string.Empty,
                            AreaType = string.Empty,
                            StorageType = string.Empty,
                            TemperatureRequirement = string.Empty,
                            HumidityRequirement = string.Empty,
                            MaxCapacity = 0,
                            CurrentUsage = 0,
                            Status = true,
                            CreatedTime = DateTime.Now,
                            UpdatedTime = null
                        };

            return await query.ToListAsync();
        }

        /// <summary>
        /// 根据条件分页查询库区设置
        /// </summary>
        /// <param name="input">查询条件</param>
        /// <returns>分页结果</returns>
        public async Task<PagedResultDto<WarehouseAreaSettingDto>> GetListAsync(GetWarehouseAreaSettingListInput input)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var query = from area in dbContext.Set<WarehouseAreaSettingModel>()
                        join warehouse in dbContext.Set<WarehouseSettingModel>()
                            on area.WarehouseId equals warehouse.Id into warehouseJoin
                        from warehouse in warehouseJoin.DefaultIfEmpty()
                        select new WarehouseAreaSettingDto
                        {
                            Id = area.Id,
                            AreaCode = area.AreaCode,
                            AreaName = area.AreaName,
                            WarehouseId = area.WarehouseId,
                            WarehouseName = warehouse != null ? warehouse.DepotName : string.Empty,
                            Area = area.Area,
                            Remark = area.Remark,
                            // 设置默认值
                            Location = string.Empty,
                            ResponsiblePerson = string.Empty,
                            AreaType = string.Empty,
                            StorageType = string.Empty,
                            TemperatureRequirement = string.Empty,
                            HumidityRequirement = string.Empty,
                            MaxCapacity = 0,
                            CurrentUsage = 0,
                            Status = true,
                            CreatedTime = DateTime.Now,
                            UpdatedTime = null
                        };

            // 应用筛选条件
            if (input.WarehouseId.HasValue && input.WarehouseId.Value > 0)
            {
                query = query.Where(q => q.WarehouseId == input.WarehouseId.Value);
            }

            if (!string.IsNullOrWhiteSpace(input.AreaCode))
            {
                query = query.Where(q => q.AreaCode.Contains(input.AreaCode));
            }

            if (!string.IsNullOrWhiteSpace(input.AreaName))
            {
                query = query.Where(q => q.AreaName.Contains(input.AreaName));
            }

            // 计算总记录数
            var totalCount = await query.CountAsync();

            // 应用分页
            query = query.OrderByDescending(q => q.Id)
                         .Skip((input.Page - 1) * input.Limit)
                         .Take(input.Limit);

            // 获取分页数据
            var items = await query.ToListAsync();

            // 返回分页结果
            return new PagedResultDto<WarehouseAreaSettingDto>
            {
                Total = totalCount,
                Items = items
            };
        }

        /// <summary>
        /// 根据ID获取库区设置
        /// </summary>
        /// <param name="id">库区设置ID</param>
        /// <returns>库区设置DTO</returns>
        public async Task<WarehouseAreaSettingDto> GetByIdAsync(int id)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var query = from area in dbContext.Set<WarehouseAreaSettingModel>()
                        join warehouse in dbContext.Set<WarehouseSettingModel>()
                            on area.WarehouseId equals warehouse.Id into warehouseJoin
                        from warehouse in warehouseJoin.DefaultIfEmpty()
                        where area.Id == id
                        select new WarehouseAreaSettingDto
                        {
                            Id = area.Id,
                            AreaCode = area.AreaCode,
                            AreaName = area.AreaName,
                            WarehouseId = area.WarehouseId,
                            WarehouseName = warehouse != null ? warehouse.DepotName : string.Empty,
                            Area = area.Area,
                            Remark = area.Remark,
                            // 设置默认值
                            Location = string.Empty,
                            ResponsiblePerson = string.Empty,
                            AreaType = string.Empty,
                            StorageType = string.Empty,
                            TemperatureRequirement = string.Empty,
                            HumidityRequirement = string.Empty,
                            MaxCapacity = 0,
                            CurrentUsage = 0,
                            Status = true,
                            CreatedTime = DateTime.Now,
                            UpdatedTime = null
                        };

            return await query.FirstOrDefaultAsync();
        }

        /// <summary>
        /// 创建库区设置
        /// </summary>
        /// <param name="input">创建库区设置DTO</param>
        /// <returns>创建的库区设置ID</returns>
        public async Task<int> CreateAsync(CreateUpdateWarehouseAreaSettingDto input)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();

            // 检查库区编码是否已存在
            if (await IsCodeExistAsync(input.AreaCode))
            {
                throw new Exception("库区编码已存在");
            }

            var entity = new WarehouseAreaSettingModel
            {
                AreaCode = input.AreaCode,
                AreaName = input.AreaName,
                WarehouseId = input.WarehouseId,
                Area = input.Area,
                Remark = input.Remark
                // 不保存数据库中不存在的字段
            };

            dbContext.Set<WarehouseAreaSettingModel>().Add(entity);
            await dbContext.SaveChangesAsync();

            return entity.Id;
        }

        /// <summary>
        /// 更新库区设置
        /// </summary>
        /// <param name="id">库区设置ID</param>
        /// <param name="input">更新库区设置DTO</param>
        /// <returns>是否更新成功</returns>
        public async Task<bool> UpdateAsync(int id, CreateUpdateWarehouseAreaSettingDto input)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var entity = await dbContext.Set<WarehouseAreaSettingModel>().FindAsync(id);

            if (entity == null)
            {
                return false;
            }

            // 检查库区编码是否已存在(排除自身)
            if (await IsCodeExistAsync(input.AreaCode, id))
            {
                throw new Exception("库区编码已存在");
            }

            entity.AreaCode = input.AreaCode;
            entity.AreaName = input.AreaName;
            entity.WarehouseId = input.WarehouseId;
            entity.Area = input.Area;
            entity.Remark = input.Remark;
            // 不更新数据库中不存在的字段

            await dbContext.SaveChangesAsync();
            return true;
        }

        /// <summary>
        /// 删除库区设置
        /// </summary>
        /// <param name="id">库区设置ID</param>
        /// <returns>是否删除成功</returns>
        public async Task<bool> DeleteAsync(int id)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var entity = await dbContext.Set<WarehouseAreaSettingModel>().FindAsync(id);

            if (entity == null)
            {
                return false;
            }

            dbContext.Set<WarehouseAreaSettingModel>().Remove(entity);
            await dbContext.SaveChangesAsync();
            return true;
        }

        /// <summary>
        /// 检查库区编码是否已存在
        /// </summary>
        /// <param name="code">库区编码</param>
        /// <param name="excludeId">排除的ID</param>
        /// <returns>是否存在</returns>
        public async Task<bool> IsCodeExistAsync(string code, int excludeId = 0)
        {
            var dbContext = await _dbContextProvider.GetDbContextAsync();
            var query = dbContext.Set<WarehouseAreaSettingModel>()
                                .Where(w => w.AreaCode == code);

            if (excludeId > 0)
            {
                query = query.Where(w => w.Id != excludeId);
            }

            return await query.AnyAsync();
        }
    }
} 